﻿using System;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.PolicyInjectionIntegrated
{
    /// <summary>
    /// 
    /// </summary>
    public class ExtendedTypeInterceptionStrategy : TypeInterceptionStrategy
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExtendedTypeInterceptionStrategy"/> class.
        /// </summary>
        /// <param name="interception">The interception.</param>
        public ExtendedTypeInterceptionStrategy(ExtendedInterception interception)
        {
            if (null == interception)
            {
                throw new ArgumentNullException("interception");
            }
            Interception = interception;
        }

        /// <summary>
        /// 
        /// <para>by tangjingbo at 2009/12/11 22:35</para>
        /// </summary>
        /// <value></value>
        public ExtendedInterception Interception { get; private set; }

        /// <summary>
        /// 
        /// <para>by tangjingbo at 2009/12/11 22:35</para>
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private static ITypeInterceptionPolicy GetInterceptionPolicy(IBuilderContext context)
        {
            var policy = context.Policies.Get<ITypeInterceptionPolicy>(context.BuildKey, false);
            if (policy == null)
            {
                policy = context.Policies.Get<ITypeInterceptionPolicy>(BuildKey.GetType(context.BuildKey), false);
            }
            return policy;
        }

        /// <summary>
        /// 
        /// <para>by tangjingbo at 2009/12/11 22:35</para>
        /// </summary>
        /// <param name="context">The context.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            ITypeInterceptionPolicy policy = GetInterceptionPolicy(context);
            if (null != policy)
            {
                if (policy.Interceptor.CanIntercept(BuildKey.GetType(context.BuildKey)))
                {
                    Interception.SetInterceptorFor(BuildKey.GetType(context.BuildKey), policy.Interceptor);
                }
            }
            else
            {
                if (Interception.Interceptor.CanIntercept(BuildKey.GetType(context.BuildKey))
                    && Interception.Interceptor is ITypeInterceptor)
                {
                    Interception.SetDefaultInterceptorFor(BuildKey.GetType(context.BuildKey),
                                                          (ITypeInterceptor) Interception.Interceptor);
                }
            }
            base.PreBuildUp(context);
        }
    }
}